﻿using System;
using System.Collections.Generic;
using System.ComponentModel;
using System.Data;
using System.Drawing;
using System.Text;
using System.Windows.Forms;
using AMVInfoSpace;
using System.IO;

namespace AMVNewsParser
{
    public partial class FormGrab : Form
    {
        public FormGrab()
        {
            InitializeComponent();
        }

        Grab grab;
        DateTime dt;

        private void btnExecute_Click(object sender, EventArgs e)
        {
            AmvHtmlParser.fPathAkrossTagReplList = Application.StartupPath + "\\AkrossTagReplList.csv";
            int startInd = Convert.ToInt32(txbMin.Text);
            int len = Convert.ToInt32(txbMax.Text) - startInd + 1;

            if (rBtnAmvNews.Checked) grab = new Grab(SITE.AMVNews, startInd, len, chbxUseWebBrowser.Checked);
            if (rBtnAkross.Checked) grab = new Grab(SITE.Akross, startInd, len, chbxUseWebBrowser.Checked);
            if (rBtnCreaCon.Checked) grab = new Grab(SITE.CreaCon, startInd, len, chbxUseWebBrowser.Checked);

            progressBar1.Value = 0;
            progressBar1.Maximum = len;
            progressBar1.Visible = true;
            btnExecute.Enabled = false;
            groupBox2.Enabled = false;
            dt = DateTime.Now;
            grab.StartGrab();
            tmrGrab.Start();
        }

        private void tmrGrab_Tick(object sender, EventArgs e)
        {
            tmrGrab.Stop();
            if (grab.Done)
            {
                progressBar1.Visible = false;
                btnExecute.Enabled = true;
                groupBox2.Enabled = true;
                MessageBox.Show("Время выполнения: " + (DateTime.Now - dt).TotalSeconds.ToString() + " секунд");
                GrabDone();
            }
            else
            {
                progressBar1.Value = grab.DoneCount;
                tmrGrab.Start();
            }
        }

        void GrabDone()
        {
            List<GrabInfo> grList = grab.GetGrabResult();

            List<AMVInfo> aInfList = new List<AMVInfo>();
            StringBuilder sb = new StringBuilder();
            DateTime dt = DateTime.Now;

            int cntOK = 0;
            List<int> notLoad = new List<int>();
            List<int> notParse = new List<int>();
            List<string> notParseErr = new List<string>();
            List<int> notCorrectPage = new List<int>();

            string site = "AMVNews";
            if (rBtnAkross.Checked) site = "Akross";
            if (rBtnCreaCon.Checked) site = "CreaCon";

            int minGoodInd = int.MaxValue;
            int maxGoodInd = int.MinValue;

            // создание AMVInfo листа и лога
            foreach (GrabInfo gInfo in grList)
            {
                if (gInfo.AmvInfo != null)
                    aInfList.Add(gInfo.AmvInfo);

                string dPath = "";
                if (gInfo.AmvInfo != null)
                {
                    if (minGoodInd > gInfo.AmvID) minGoodInd = gInfo.AmvID;
                    if (maxGoodInd < gInfo.AmvID) maxGoodInd = gInfo.AmvID;
                    cntOK++;
                }
                else if (gInfo.LoadEx != null) notLoad.Add(gInfo.AmvID);
                else if (gInfo.ParseEx != null)
                {
                    dPath = Gl.dPathAMVInfoResult + "\\PageNotParse_" + site + "_" + dt.ToString("yyyy_MM_dd_HH_mm_ss");
                    if (!Directory.Exists(dPath)) Directory.CreateDirectory(dPath);
                    File.WriteAllText(dPath + "\\" + gInfo.AmvID.ToString() + ".html", gInfo.Html, Encoding.UTF8);
                    notParse.Add(gInfo.AmvID);
                    notParseErr.Add(gInfo.ParseEx.Message);
                }
                else if (!gInfo.PageIsCorrect)
                {
                    dPath = Gl.dPathAMVInfoResult + "\\PageNotCorrect_" + site + "_" + dt.ToString("yyyy_MM_dd_HH_mm_ss");
                    if (!Directory.Exists(dPath)) Directory.CreateDirectory(dPath);
                    File.WriteAllText(dPath + "\\" + gInfo.AmvID.ToString() + ".html", gInfo.Html, Encoding.UTF8);
                    notCorrectPage.Add(gInfo.AmvID);
                }

                BuildParseLog(gInfo, sb);
            }

            if (minGoodInd == int.MaxValue)
            {
                minGoodInd = Convert.ToInt32(txbMin.Text.Trim());
                maxGoodInd = Convert.ToInt32(txbMax.Text.Trim());
            }

            // подробный отчет
            File.WriteAllText(Gl.dPathAMVInfoResult + string.Format("\\AMVInfoDetail_{0}_{1}-{2}_[{3}].log", site, minGoodInd, maxGoodInd, dt.ToString("yyyy_MM_dd_HH_mm_ss")), sb.ToString());

            // лог
            sb = new StringBuilder();
            sb.AppendLine(string.Format("Всего страниц: {0}. (с {1} по {2})", grList.Count, txbMin.Text, txbMax.Text));
            sb.AppendLine("Обработано корректно страниц: " + cntOK.ToString());
            sb.AppendLine("Не удалось загрузить страниц: " + notLoad.Count.ToString());
            foreach (int ind in notLoad) sb.AppendLine("\t" + ind.ToString());
            sb.AppendLine("Не удалось распарсить старинц: " + notParse.Count.ToString());
            for (int i = 0; i < notParse.Count; i++)
            {
                sb.AppendLine("\t" + notParse[i].ToString());
                sb.AppendLine("\tОшибка:" + notParseErr[i]);
            }
            sb.AppendLine("Отсутствуют корректные страницы: " + notCorrectPage.Count.ToString());
            foreach (int ind in notCorrectPage) sb.AppendLine("\t" + ind.ToString());

            AmvHtmlParser.SaveAmvInfoList(Gl.dPathAMVInfoResult + string.Format("\\AMVInfo_{0}_{1}-{2}_[{3}].aInf", site, minGoodInd, maxGoodInd, dt.ToString("yyyy_MM_dd_HH_mm_ss")), aInfList);
            File.WriteAllText(Gl.dPathAMVInfoResult + string.Format("\\AMVInfo_{0}_{1}-{2}_[{3}].log", site, minGoodInd, maxGoodInd, dt.ToString("yyyy_MM_dd_HH_mm_ss")), sb.ToString());

        }

        void BuildParseLog(GrabInfo GrInfo, StringBuilder Sb)
        {
            Sb.AppendLine("UIN: " + GrInfo.AmvID.ToString());

            if (GrInfo.AmvInfo == null)
            {
                if (GrInfo.LoadEx != null)
                {
                    AddLogExeption(Sb, "ОШИБКА ЗАГРУЗКИ:", GrInfo.LoadEx);
                }
                else if (GrInfo.ParseEx != null)
                {
                    AddLogExeption(Sb, "ОШИБКА ПАРСИНГА:", GrInfo.ParseEx);
                }
                else if (!GrInfo.PageIsCorrect)
                {
                    Sb.AppendLine("Страница некорректна");
                }
                Sb.AppendLine("---------------------------------------------------------------------------------------------");
                return;
            }

            AMVInfo AmvInfo = GrInfo.AmvInfo;

            Sb.AppendLine("НАЗВАНИЕ: " + AmvInfo.Name);
            Sb.AppendLine("ОЦЕНКА: " + AmvInfo.Rating.ToString());
            Sb.AppendLine("Дата создания: " + AmvInfo.CreateDate.ToString("dd.MM.yyyy HH.mm.ss"));
            Sb.AppendLine("Дата добавления: " + AmvInfo.AppenedDate.ToString("dd.MM.yyyy HH.mm.ss"));
            Sb.AppendLine("-------------");

            Sb.AppendLine("<ТЕГИ жанры>");
            foreach (string str in AmvInfo.TagGenre)
                Sb.AppendLine(str);
            Sb.AppendLine("<ТЕГИ прочие>");
            foreach (string str in AmvInfo.TagOther)
                Sb.AppendLine(str);
            Sb.AppendLine("-------------");

            Sb.AppendLine("<КОММЕНТАРИЙ>");
            Sb.AppendLine(AmvInfo.Comment);
            Sb.AppendLine("-------------");

            Sb.AppendLine("<АНИМЕ>");
            foreach (string str in AmvInfo.Anm)
                Sb.AppendLine(str);
            Sb.AppendLine("-------------");

            Sb.AppendLine("<МУЗЫКА>");
            foreach (string str in AmvInfo.Msc)
                Sb.AppendLine(str);
            Sb.AppendLine("-------------");

            Sb.AppendLine("<НАГРАДЫ>");
            foreach (string str in AmvInfo.Awd)
                Sb.AppendLine(str);
            Sb.AppendLine("-------------");

            Sb.AppendLine("<АВТОРЫ>");
            foreach (string str in AmvInfo.Atr)
                Sb.AppendLine(str);

            Sb.AppendLine("---------------------------------------------------------------------------------------------");

        }

        void AddLogExeption(StringBuilder Sb, string Mess, Exception Ex)
        {
            Sb.AppendLine(Mess);
            Sb.AppendLine(Ex.Message);
            Sb.AppendLine("Трассировка: " + Ex.StackTrace);
            if (Ex.InnerException != null) AddLogExeption(Sb, "--- Дочернее исключение ------", Ex.InnerException);
        }

    }
}
